Skip to content

Fix IPv6 extension header length calculation in dhcp6relay#103

Merged
Xichen96 merged 1 commit intosonic-net:masterfrom
xq9mend:fix/f027-dhcpv6-ext-header-len
Apr 28, 2026
Merged

Fix IPv6 extension header length calculation in dhcp6relay#103
Xichen96 merged 1 commit intosonic-net:masterfrom
xq9mend:fix/f027-dhcpv6-ext-header-len

Conversation

@xq9mend
Copy link
Copy Markdown
Contributor

@xq9mend xq9mend commented Apr 24, 2026

Why I did it

The IPv6 extension header parsing loop in dhcp6relay advances the current position by the raw ip6e_len byte value. Per RFC 2460/8200, ip6e_len is in units of 8 octets, not counting the first 8 bytes, so the correct advance is (ip6e_len + 1) * 8. Using the raw value causes header misparse for any packet with nonzero ip6e_len, which can lead to incorrect DHCPv6 relay behavior or process crash from L2-adjacent hosts.

How I did it

Replace the raw byte advance with the RFC-mandated formula:

current_position += (ext_header->ip6e_len + 1) * 8;

Add a unit test covering the nonzero ip6e_len case (Hop-by-Hop extension header with ip6e_len=1, which should advance 16 bytes). The existing tests only covered ip6e_len=0, which was partially mitigated by a separate guard.

How to verify it

cd src/dhcprelay/dhcp6relay && make test
[==========] 46 tests from 10 test suites ran.
[  PASSED  ] 46 tests.

Per RFC 2460/8200, ip6e_len is in units of 8 octets, not counting the
first 8 bytes. The correct advance is (ip6e_len + 1) * 8, not the raw
byte value.

Add a unit test with a Hop-by-Hop extension header (ip6e_len=1) to
cover the nonzero case, which was previously untested.

Signed-off-by: xq9mend <[email protected]>
@mssonicbld
Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@xq9mend
Copy link
Copy Markdown
Contributor Author

xq9mend commented Apr 25, 2026

@Blueve @cshivashgit

@Blueve Blueve requested a review from Xichen96 April 28, 2026 00:01
Comment thread dhcp6relay/src/relay.cpp
ext_header = (const struct ip6_ext *)current_position;
current_position += ext_header->ip6e_len;
current_position += (ext_header->ip6e_len + 1) * 8;
if((current_position == prev) ||
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

current_position wont be prev under current calculation

@Xichen96 Xichen96 merged commit 9b69260 into sonic-net:master Apr 28, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants